#include "animationdatahandler.h"

 AnimationDataHandler* AnimationDataHandler::_instance = NULL;

AnimationDataHandler::AnimationDataHandler(QObject *parent) :
    QObject(parent),
    m_currentAction(NULL)
{
}

AnimationDataHandler::~AnimationDataHandler()
{
    clearAllData();
}

AnimationDataHandler* AnimationDataHandler::instance()
{
    if(_instance == NULL)
    {
        _instance = new AnimationDataHandler();
    }

    return _instance;
}

void AnimationDataHandler::purgeInstance()
{
    CC_SAFE_DELETE_NULL(_instance);
}

bool AnimationDataHandler::isValidIndex(int index)
{
    if(index < 0 || index >= m_actionList.count())
    {
        return false;
    }

    return true;
}

int AnimationDataHandler::getCurrenFrameIndex()
{
    if(m_currentAction == NULL) return -1;
    return m_currentAction->getCurrentFrameIndex();
}

PlistFrameInfo* AnimationDataHandler::getCurrentFrame()
{
    if(m_currentAction == NULL) return NULL;
    return m_currentAction->getCurrentFrame();
}

void AnimationDataHandler::appendNewActionData()
{
    m_currentAction = new Action();
    m_actionList.append(m_currentAction);;

    emit notifyActionDataChangeUpdate();
}

void AnimationDataHandler::removeActionByIndex(int index)
{
     if(!isValidIndex(index)) return;

     Action* action = m_actionList.at(index);
     if(action == NULL) return;

     CC_SAFE_DELETE_NULL(action);

     m_actionList.removeAt(index);

     if(m_actionList.count() == 0)
     {
         m_currentAction = NULL;
     }

     emit notifyActionDataChangeUpdate();
}

void AnimationDataHandler::removeFrameByIndex(int index)
{
    if(m_currentAction == NULL) return;

    m_currentAction->removeFrameByIndex(index);

    emit notifyFrameDataChangeUpdate();
}

void AnimationDataHandler::appendFrameList(const PlistFrameInfoList &frameList)
{
    if(m_currentAction == NULL) return;

    m_currentAction->appendPlistInfo(frameList);

    m_currentAction->appendFrameList(frameList);

    emit notifyFrameDataChangeUpdate();

}

void AnimationDataHandler::setCurrentFrameByIndex(int index)
{
    if(m_currentAction == NULL) return;

    m_currentAction->setCurrentFrameByIndex(index);

    emit notifyFrameDataChangeUpdate();
}

void AnimationDataHandler::setCurrentActionByIndex(int index)
{   
    if(!isValidIndex(index))
    {
        return;
    }

    m_currentAction = m_actionList.at(index);

    emit notifyActionDataChangeUpdate();
}

void AnimationDataHandler::convertStringListToDom(QDomElement &element, QString attribute, QStringList &list)
{
    QString value;
    for(int index = 0; index < list.length(); index++)
    {
        value.append(list.at(index)).append(",");
    }

    int index = value.lastIndexOf(",");
    value.remove(index,1);

    element.setAttribute(attribute, value);
}

void AnimationDataHandler::convertDomToStringList(QDomElement &element, QString attribute, QStringList &list)
{
    QStringList stringList =  element.attribute(attribute).split(",");
    list.append(stringList);
}

const QDomDocument* AnimationDataHandler::convertToDomDocument()
{
    QDomDocument* doc = new QDomDocument();
    doc->appendChild(doc->createProcessingInstruction("xml","version=\"1.0\" encoding=\"UTF-8\""));

    QDomElement rootElement = doc->createElement("PlistAnimation");
    rootElement.setAttribute("verstion", "1.0");
    doc->appendChild(rootElement);

    QDomElement actionRootElement = doc->createElement("actionList");
    actionRootElement.setAttribute("actionNum", m_actionList.count());

    doc->appendChild(rootElement);
    rootElement.appendChild(actionRootElement);

    for(int index = 0; index < m_actionList.count(); index ++)
    {
         Action* action = m_actionList.at(index);
         QDomElement actionElement = doc->createElement("action");
         actionElement.setAttribute("name",action->getName());
         actionElement.setAttribute("frameNum",action->getFrameCount());
         actionElement.setAttribute("delay",action->getDelay());
         convertStringListToDom(actionElement,QString("plistName"),action->getPlistName());
         convertStringListToDom(actionElement,QString("pngName"),action->getPlistPngName());

         action->convertFramenToDom(actionElement,doc);

         actionRootElement.appendChild(actionElement);
    }

    return doc;
}

bool AnimationDataHandler::loadFromFile(QFile& file)
{
    QDomDocument doc;
    if(!doc.setContent(&file))
    {
        return false;
    }

    clearAllData();

    QDomElement rootElement = doc.childNodes().at(1).toElement();
    if(rootElement.tagName() != "PlistAnimation")
    {
        return false;
    }

    QDomNode actionRootElement = rootElement.childNodes().at(0);

    QDomNodeList actionList = actionRootElement.childNodes();

    for(int index = 0; index < actionList.count(); index ++)
    {
        QDomElement actionElement = actionList.at(index).toElement();

        Action* action = new Action();
        action->setName(actionElement.attribute("name"));
        action->setDelay(actionElement.attribute("delay").toFloat());        
        convertDomToStringList(actionElement, "plistName",action->getPlistName());
        convertDomToStringList(actionElement, "pngName",action->getPlistPngName());

        action->loadFromDom(actionElement);

        m_actionList.append(action);
    }

    if(m_actionList.count() != 0)
    {
        m_currentAction = m_actionList.at(0);
    }
    else
    {
        m_currentAction = NULL;
    }


    emit notifyAllDataChangeUpdate();

    return true;
}

bool AnimationDataHandler::clearAllData()
{
    ActionList::iterator it;
    for(it = m_actionList.begin(); it != m_actionList.end(); it ++)
    {
        CC_SAFE_DELETE_NULL(*it);
    }

    m_actionList.clear();
    m_currentAction = NULL;
}


void AnimationDataHandler::resetAll()
{
    clearAllData();

    emit notifyAllDataChangeUpdate();
}



